package cm.sms.impl;

import cm.sms.DO.SmsChannelDO;
import cm.sms.mapper.SmsChannelMapper;
import cm.sms.property.SmsChannelProperties;
import cm.sms.service.SmsChannelService;
import cm.utils.CollectionUtils;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author: yxh
 * @Description: 短信渠道
 * @Date: Created in 2022/9/20 13:43
 * @Modified By:
 */
@Service
@Slf4j
public class SmsChannelServiceImpl implements SmsChannelService {

    @Resource
    private SmsChannelMapper smsChannelMapper;

    /**
     * 缓存菜单的最大更新时间，用于后续的增量轮询，判断是否有更新
     */
    private volatile Date maxUpdateTime;

    @Override
    public SmsChannelDO getSmsChannel(Long channelId) {
        return smsChannelMapper.selectById(channelId);
    }

    @Override
    public SmsChannelDO getSmsChannelByCode(String code) {
        QueryWrapper<SmsChannelDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(StringUtils.isNotBlank(code),SmsChannelDO::getCode,code)
                .orderByDesc(SmsChannelDO::getId)
                .last("limit 1");
    return smsChannelMapper.selectOne(queryWrapper);
    }

    @Override
    @PostConstruct
    public void initSmsClients() {
        // 获取短信渠道，如果有更新
        List<SmsChannelDO> smsChannels = this.loadSmsChannelIfUpdate(maxUpdateTime);
        if (CollUtil.isEmpty(smsChannels)) {
            return;
        }
        // 创建或更新短信 Client
//        List<SmsChannelProperties> propertiesList = SmsChannelConvert.INSTANCE.convertList02(smsChannels);
//        propertiesList.forEach(properties -> smsClientFactory.createOrUpdateSmsClient(properties));

        // 写入缓存
        maxUpdateTime = CollectionUtils.getMaxValue(smsChannels, SmsChannelDO::getUpdateTime);
        log.info("[initSmsClients][初始化 SmsChannel 数量为 {}]", smsChannels.size());
    }

    /**
     * 如果短信渠道发生变化，从数据库中获取最新的全量短信渠道。
     * 如果未发生变化，则返回空
     *
     * @param maxUpdateTime 当前短信渠道的最大更新时间
     * @return 短信渠道列表
     */
    private List<SmsChannelDO> loadSmsChannelIfUpdate(Date maxUpdateTime) {
        // 第一步，判断是否要更新。
        if (maxUpdateTime == null) { // 如果更新时间为空，说明 DB 一定有新数据
            log.info("[loadSmsChannelIfUpdate][首次加载全量短信渠道]");
        } else { // 判断数据库中是否有更新的短信渠道
            if (smsChannelMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
                return null;
            }
            log.info("[loadSmsChannelIfUpdate][增量加载全量短信渠道]");
        }
        // 第二步，如果有更新，则从数据库加载所有短信渠道
        return smsChannelMapper.selectList();
    }

}
